from tools9 import (minutes_to_time,calculate_load_time,time_to_minutes,
                    calculate_work_end_time,check_ab_vehicles,parse_shift,
                    safe_parse_list,get_allowed_shifts,calculate_work_start_time,
                    calculate_work_start_time,calculate_unload_done_time,calculate_arrive_time,
                    double_zero_priority_sort,check_ab_vehicles)

# 把单顶分为上午的单顶和下午的单顶分别安排

def single_top_tasks_morning(df,driver_df,vehicle_df,assigned_vehicles, assigned_drivers):
    '''
    筛选单顶
    '''

    result_df = []
    # 筛选单顶任务
    single_top_df = df[df['cargo_type']=="单顶" ].copy()
    single_top_df = single_top_df[single_top_df['load_time'].apply(time_to_minutes) <= 12 * 60]
    for _, task in single_top_df.iterrows():

        result = single_top_task_morning(task,driver_df,vehicle_df,assigned_vehicles,assigned_drivers)
        assigned_vehicles.add(result['车辆ID'])
        assigned_drivers.add(result['司机姓名'])
        result_df.append(result)
    return result_df,assigned_vehicles,assigned_drivers

def single_top_tasks_afternoon(df,driver_df,vehicle_df,assigned_vehicles, assigned_drivers):
    '''筛选单顶
    '''
    result_df = []
    # 筛选单顶任务
    single_top_df = df[df['cargo_type']=="单顶"].copy()
    single_top_df = single_top_df[single_top_df['load_time'].apply(time_to_minutes) > 12 * 60]
    for _, task in single_top_df.iterrows():

        result = single_top_task_afternoon(task,driver_df,vehicle_df,assigned_vehicles,assigned_drivers)
        assigned_vehicles.add(result['车辆ID'])
        assigned_drivers.add(result['司机姓名'])
        result_df.append(result)
    return result_df,assigned_vehicles,assigned_drivers

def single_top_task_morning(task,driver_df,vehicle_df,assigned_vehicles,assigned_drivers):

    departure_time = task['departure_time']
    task_shift = parse_shift(departure_time)
    # 先安排司机
    selected_driver = assign_driver_for_morning_single_top(
        task, task_shift,driver_df, assigned_drivers
    )

    selected_vehicle = assign_vehicle_for_single_top(
        task, vehicle_df, assigned_vehicles,selected_driver
    )

    # 计算到货时间
    arrive_time = calculate_arrive_time(cargo_type=task['cargo_type'],
                                        dep_time=task['departure_time'],
                                        is_second_special=True if id == 1 else False
                                        )
    # 计算卸货完成时间
    unload_done_time = calculate_unload_done_time(arrive_time=arrive_time,
                                                  cargo_type=task['cargo_type'],
                                                  load_time=task['load_time']
                                                  )
    # 计算收车时间
    end_time = calculate_work_end_time(cargo_type=task['cargo_type'],
                                       unload_done_time=unload_done_time,
                                       region=selected_driver['region'],
                                       is_transfer=task['is_transfer'],
                                       load_time=task['load_time']
                                       )

    return {
        '发车时间': departure_time,
        '装货时间': task['load_time'],
        '货物类型': '单顶',
        '车辆ID': selected_vehicle['vehicle_id'],
        '车辆类型': selected_vehicle['type'],
        '车牌号': selected_vehicle['plate_number'],
        '司机ID': selected_driver['driver_id'],
        '司机姓名': selected_driver['driver_name'],
        '司机所属地区': selected_driver['region'],
        '是否接车': task['is_transfer'],
        '收车时间': end_time
    }

def single_top_task_afternoon(task,driver_df,vehicle_df,assigned_vehicles,assigned_drivers):

    departure_time = task['departure_time']
    task_shift = parse_shift(departure_time)
    # 先安排司机
    selected_driver = assign_driver_for_afternoon_single_top(
        task, task_shift, driver_df, assigned_drivers
    )

    selected_vehicle = assign_vehicle_for_single_top(
        task, vehicle_df, assigned_vehicles,selected_driver
    )

    # 计算到货时间
    arrive_time = calculate_arrive_time(cargo_type=task['cargo_type'],
                                        dep_time=task['departure_time'],
                                        is_second_special=True if id == 1 else False
                                        )
    # 计算卸货完成时间
    unload_done_time = calculate_unload_done_time(arrive_time=arrive_time,
                                                  cargo_type=task['cargo_type'],
                                                  load_time=task['load_time']
                                                  )
    # 计算收车时间
    end_time = calculate_work_end_time(cargo_type=task['cargo_type'],
                                       unload_done_time=unload_done_time,
                                       region=selected_driver['region'],
                                       is_transfer=task['is_transfer'],
                                       load_time=task['load_time']
                                       )

    return {
        '发车时间': departure_time,
        '装货时间': task['load_time'],
        '货物类型': '单顶',
        '车辆ID': selected_vehicle['vehicle_id'],
        '车辆类型': selected_vehicle['type'],
        '车牌号': selected_vehicle['plate_number'],
        '司机ID': selected_driver['driver_id'],
        '司机姓名': selected_driver['driver_name'],
        '司机所属地区': selected_driver['region'],
        '是否接车': task['is_transfer'],
        '收车时间': end_time
    }



def assign_driver_for_morning_single_top(task, task_shift, driver_df, assigned_drivers):
    '''
    1.早上的都可以，
    2. 早晚班
    3. 单顶次数
    4. 休息时间
    '''
    available_drivers = driver_df[
            (~driver_df['driver_name'].isin(assigned_drivers))].copy()
    available_drivers['history_shifts'] = available_drivers['last_4days_departure_times'].apply(
        lambda x: [parse_shift(t) for t in safe_parse_list(x) if t is not None]
    )
    available_drivers['allowed_shifts'] = available_drivers['history_shifts'].apply(get_allowed_shifts)
    available_drivers = available_drivers[
        available_drivers['allowed_shifts'].apply(lambda x: task_shift in x if x else False)
    ]
    available_drivers['start_time'] = available_drivers['region'].apply(
        lambda x: calculate_work_start_time(load_time=task['load_time'],
                                            departure_time=task['departure_time'],
                                            region=x,
                                            cargo_type=task['cargo_type'])
    )
    available_drivers['time_priority'] = time_to_minutes(available_drivers['start_time']) - time_to_minutes(
        available_drivers['end_time'])


    available_drivers = available_drivers.sort_values(
        by=['time_priority','season_single_top_count','driver_id'],
        ascending=[False, True, True]
    )
    return available_drivers.iloc[0]

def assign_driver_for_afternoon_single_top(task, task_shift, driver_df, assigned_drivers):
    '''
    1.下午的只能长沙
    2. 早晚班
    3. 单顶次数
    4. 休息时间
    '''
    available_drivers = driver_df[
            (~driver_df['driver_name'].isin(assigned_drivers)) &
            (driver_df['region'] == '长沙')].copy()
    available_drivers['history_shifts'] = available_drivers['last_4days_departure_times'].apply(
        lambda x: [parse_shift(t) for t in safe_parse_list(x) if t is not None]
    )
    available_drivers['allowed_shifts'] = available_drivers['history_shifts'].apply(get_allowed_shifts)
    available_drivers = available_drivers[
        available_drivers['allowed_shifts'].apply(lambda x: task_shift in x if x else False)
    ]
    available_drivers['start_time'] = available_drivers['region'].apply(
        lambda x: calculate_work_start_time(load_time=task['load_time'],
                                            departure_time=task['departure_time'],
                                            region=x,
                                            cargo_type=task['cargo_type'])
    )
    available_drivers['time_priority'] = time_to_minutes(available_drivers['start_time']) - time_to_minutes(
        available_drivers['end_time'])


    available_drivers = available_drivers.sort_values(
        by=['time_priority','season_single_top_count','driver_id'],
        ascending=[False, True, True]
    )
    return available_drivers.iloc[0]


def assign_vehicle_for_single_top(task, vehicle_df, assigned_vehicles, selected_driver):
    '''

    1. 筛选已经排完的车
    2. 车的地区和人的地区一致
    3.表里面车型一致
    4. ab角
    '''
    available_vehicles = vehicle_df[~vehicle_df['vehicle_id'].isin(assigned_vehicles)&
                                   (task['vehicle_type'] == vehicle_df['type'])
                                   ].copy()
    # 出车时间与收车时间间隔大于9小时
    available_vehicles = available_vehicles[
        time_to_minutes(selected_driver['start_time']) - time_to_minutes(available_vehicles['end_time']) < 900]

    # 计算AB角优先级
    available_vehicles['ab_priority'] = available_vehicles['ab_drivers'].apply(
        lambda x: check_ab_vehicles(x, selected_driver['driver_name'])
    )

    # 按AB角优先级排序（A角优先），然后按司机ID排序
    available_vehicles = available_vehicles.sort_values(
        by=['ab_priority', 'vehicle_id'],
        ascending=[False, True]
    )
    if available_vehicles.empty:

        return None  # 或者适当的错误处理
    selected_vehicle = available_vehicles.iloc[0]

    if selected_vehicle is None:
        print(f"没有可用车辆用于单顶任务: {task['departure_time']}")
        return None

    return selected_vehicle








